package com.pb.infra.auth.service;

import com.pb.infra.auth.entity.pbsys.PriviPosition;
import com.pb.infra.auth.entity.pbsys.PriviPositionExample;
import com.pb.infra.auth.entity.pbsys.PriviStruct;
import com.pb.infra.auth.entity.pbsys.PriviStructExample;
import com.pb.infra.auth.mapper.custom.PriviStructCustomMapper;
import com.pb.infra.auth.mapper.pbsys.PriviPositionMapper;
import com.pb.infra.auth.mapper.pbsys.PriviStructMapper;
import com.pb.infra.oth.entity.common.Result;
import com.pb.infra.oth.util.Constant;
import com.pb.infra.oth.util.DateTimeUtil;
import com.pb.infra.oth.util.JwtTokenConfig;
import com.pb.infra.oth.util.StringUtil;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 组织架构管理
 *
 * @author liudebao
 * @date 2020/12/25
 */
@Service
public class PriviStructService {

    /**
     * 组织架构单表DAO映射
     */
    @Resource
    private PriviStructMapper priviStructMapper;

    /**
     * 组织架构多表DAO映射
     */
    @Resource
    private PriviStructCustomMapper priviStructCustomMapper;

    /**
     * 职位表DAO映射
     */
    @Resource
    private PriviPositionMapper priviPositionMapper;

    /**
     * jwttoken配置类
     */
    @Resource
    private JwtTokenConfig jwtTokenConfig;

    @Resource
    private CommonService commonService;

    /**
     * 查询法人所有组织架构
     *
     * @param map
     * @return
     */
    public Result select(Map<String, Object> map) {
        if (!StringUtil.isEmpty(map.get("allFlag")) && "1".equals(map.get("allFlag").toString())) {
            List<Map<String, Object>> list = priviStructCustomMapper.getOrg(map);
            if (list != null && list.size() > 0 && (!StringUtil.isEmpty(map.get("structId")) || !StringUtil.isEmpty(map.get("structName")))) {
                Set<String> list1 = new HashSet<>();
                for (int i = 0; i < list.size(); i++) {
                    if (!StringUtil.isEmpty(list.get(i).get("nodePath"))) {
                        String path = list.get(i).get("nodePath").toString();
                        String[] str = path.split("\\.");
                        for (int j = 0; j < str.length; j++) {
                            list1.add(str[j]);
                        }
                    }
                }
                map.put("list", new ArrayList<>(list1));
                List<Map<String , Object>> listDate = priviStructCustomMapper.getOrgOne(map);
                return Result.ok(listDate);
            } else {
                return Result.ok(list);
            }
        } else {
            List<Map<String, Object>> list = priviStructCustomMapper.getOrgByCorp(map);
            if (list != null && list.size() > 0 && (!StringUtil.isEmpty(map.get("structId")) || !StringUtil.isEmpty(map.get("structName")))) {
                Set<String> list1 = new HashSet<>();
                for (int i = 0; i < list.size(); i++) {
                    if (!StringUtil.isEmpty(list.get(i).get("nodePath"))) {
                        String path = list.get(i).get("nodePath").toString();
                        String[] str = path.split("\\.");
                        for (int j = 0; j < str.length; j++) {
                            list1.add(str[j]);
                        }
                    }
                }
                map.put("list", new ArrayList<>(list1));
                List<Map<String , Object>> listDate = priviStructCustomMapper.getOrgOne(map);
                return Result.ok(listDate);
            } else {
                return Result.ok(list);
            }
        }
    }

    /**
     * 新增组织架构
     *
     * @param map 请求参数
     * @return Map<String, Object> 操作返回结果
     */
    @Transactional
    public Result insert(Map<String, Object> map, HttpServletRequest request) {
        PriviStruct priviOrg1 = priviStructMapper.selectByPrimaryKey(map.get("structId").toString());
        if (priviOrg1 != null && !StringUtil.isEmpty(priviOrg1.getStructId())) {
            return Result.error("-1", "该组织已存在");
        } else {
            PriviStruct priviStruct = new PriviStruct();
            priviStruct.setCorpId(map.get("corpId").toString());
            priviStruct.setStructId(map.get("structId").toString());
            priviStruct.setStructName(map.get("structName").toString());
            priviStruct.setStructType(map.get("structType").toString());
            priviStruct.setUpperId(map.get("upperId").toString());
            priviStruct.setStructLabel(map.get("structLabel").toString());
            Map<String, Object> map1 = new HashMap<>();
            map1.put("structId", map.get("upperId").toString());
            List<Map<String, Object>> list = priviStructCustomMapper.selPath(map1);
            if (list != null && list.size() > 0) {
                priviStruct.setNodePath(list.get(0).get("nodePath").toString() + priviStruct.getStructId() + ".");
                if (StringUtil.isEmpty(priviStruct.getLevelId())) {
                    priviStruct.setLevelId(new BigDecimal(Integer.parseInt(list.get(0).get("levelId").toString()) + 1));
                }
            } else {
                priviStruct.setNodePath("." + priviStruct.getStructId() + ".");
                priviStruct.setLevelId(new BigDecimal(1));
            }
            //获取序号
            List<Map<String , Object>> listDate = priviStructCustomMapper.getMaxSeriaNo();
            listDate.forEach((item)->{
                if (!StringUtil.isEmpty(item.get("serialNo"))) {
                    BigDecimal serialNo = new BigDecimal(item.get("serialNo").toString());
                    priviStruct.setSerialNo(serialNo);
                }
                /*BigDecimal serialNo=(BigDecimal) item.get("serialNo");
                priviStruct.setSerialNo(serialNo);*/
            });
            String token = request.getHeader(jwtTokenConfig.getHeader());
            Claims claims = jwtTokenConfig.getClaimByToken(token);
            String userId = (String)claims.get(jwtTokenConfig.getSub());
            priviStruct.setCreateUser(userId);
            priviStruct.setCreateTime(DateTimeUtil.getStrFromNewDate());
            priviStruct.setUpdateUser(userId);
            priviStruct.setUpdateTime(DateTimeUtil.getStrFromNewDate());
            if (!StringUtil.isEmpty(map.get("structAttr"))) {
                priviStruct.setStructAttr(map.get("structAttr").toString());
            }
            priviStructMapper.insertSelective(priviStruct);
            return Result.OK_EMPTY;
        }
    }

    /**
     * 修改组织架构
     *
     * @param map 请求参数
     * @return Map<String, Object> 操作返回结果
     */
    @Transactional
    public void update(Map<String, Object> map, HttpServletRequest request) {
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        PriviStruct priviStruct = new PriviStruct();
        priviStruct.setUpdateUser(userId);
        priviStruct.setUpdateTime(DateTimeUtil.getStrFromNewDate());
        priviStruct.setStructId(map.get("structId").toString());
        priviStruct.setStructName(map.get("structName").toString());
        priviStruct.setStructLabel(map.get("structLabel").toString());
        priviStruct.setUpperId(map.get("upperId").toString());
        priviStruct.setNodePath(map.get("nodePath").toString());
        if (!StringUtil.isEmpty(map.get("nodePath").toString()) && Constant.EXIST.equals(map.get("nodePath").toString())) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("structId", map.get("upperId").toString());
            List<Map<String, Object>> list = priviStructCustomMapper.selPath(map1);
            if (list != null && list.size() > 0) {
                priviStruct.setNodePath(list.get(0).get("nodePath").toString() + priviStruct.getStructId() + ".");
            } else {
                priviStruct.setNodePath("." + priviStruct.getStructId() + ".");
            }
            updatePath(priviStruct.getStructId(), priviStruct.getNodePath());
        } else {
            priviStruct.setNodePath("");
        }
        if (!StringUtil.isEmpty(map.get("structAttr"))) {
            priviStruct.setStructAttr(map.get("structAttr").toString());
        } else {
            priviStruct.setStructAttr("");
        }
        priviStructMapper.updateByPrimaryKeySelective(priviStruct);
    }

    /**
     * 修改树节点路径
     * @param parentId
     * @param nodePath
     */
    public void updatePath(String parentId, String nodePath) {
        PriviStructExample priviOrgExample = new PriviStructExample();
        PriviStructExample.Criteria criteria = priviOrgExample.createCriteria();
        criteria.andUpperIdEqualTo(parentId);
        List<PriviStruct> list = priviStructMapper.selectByExample(priviOrgExample);
        if (list != null) {
            for (int i = 0; i < list.size(); i++) {
                PriviStruct priviOrg = list.get(i);
                priviOrg.setNodePath(nodePath + priviOrg.getStructId() + ".");
                priviStructMapper.updateByPrimaryKeySelective(priviOrg);
                updatePath(priviOrg.getStructId(), priviOrg.getNodePath());
            }
        }
    }

    /**
     * 删除组织架构
     *
     * @param map 请求参数
     * @return Map<String, Object> 操作返回结果
     */
    @Transactional
    public boolean delete(List<String> map) {
        // 删除参数
        boolean flag = false;
        for (String appId : map) {
            PriviPositionExample priviPositionExample = new PriviPositionExample();
            PriviPositionExample.Criteria criteria = priviPositionExample.createCriteria();
            //criteria.andOrgIdEqualTo(appId);
            criteria.andStructIdEqualTo(appId);
            criteria.andDeleteFlagEqualTo("0");
            List<PriviPosition> list = priviPositionMapper.selectByExample(priviPositionExample);
            if (list != null && list.size() > 0) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            for (String appId : map) {
                /*PriviOrg priviOrg = new PriviOrg();
                priviOrg.setOrgId(appId);
                priviOrg.setDeleteFlag(Constant.EXIST);
                priviOrgMapper.updateByPrimaryKeySelective(priviOrg);*/
                PriviStruct priviOrg = new PriviStruct();
                priviOrg.setStructId(appId);
                priviOrg.setDeleteFlag(Constant.EXIST);
                priviStructMapper.updateByPrimaryKeySelective(priviOrg);
            }
        }
        return flag;
    }

    /**
     * 恢复组织架构
     * @param map
     */
    @Transactional
    public void updateFlag(List<String> map) {
        for (String appId : map) {
            PriviStruct priviOrg = new PriviStruct();
            priviOrg.setStructId(appId);
            priviOrg.setDeleteFlag(Constant.OK);
            priviStructMapper.updateByPrimaryKeySelective(priviOrg);
        }
    }

    public List<Map<String, Object>> getAllOrg() {
        return priviStructCustomMapper.getAllOrg();
    }

    @Transactional
    public String importExcel(List<List<Map<String,Object>>> data, String userId){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        String date = df.format(calendar.getTime());
        String msg="";
        StringBuilder stringBuffer = new StringBuilder();
        List<Map<String,Object>> addList =new ArrayList<>();
        Result attrResult = commonService.selBusiCode("S02");
        List<Map<String, Object>> attrList = (List<Map<String, Object>>)attrResult.getData();
        Result corpResult = commonService.selAllCorpList();
        List<Map<String, Object>> corpList = (List<Map<String, Object>>)corpResult.getData();
        boolean fialFlag=false;
        List<String> idList = new ArrayList<>();
        for (int i = 0; i <data.size() ; i++) {
            List<Map<String,Object>> list =data.get(i);
            for (Map<String,Object> map : list) {
                if (!StringUtil.isEmpty(map.get("structId"))) {
                    idList.add(map.get("structId").toString());
                }
            }
        }
        for (int i = 0; i <data.size() ; i++) {
            List<Map<String,Object>> list =data.get(i);
            int n=2;
            for (Map<String,Object> map : list) {
                boolean msgFlag=false;
                StringBuffer sbf=new StringBuffer();
                if(!msgFlag){
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第<b>"+(n)+"</b>行数据:<br/>");
                }
                map.put("debugFlag","1");
                map.put("deleteFlag","0");
                map.put("date",date);
                List<Map<String, Object>> structList = priviStructCustomMapper.selPath(map);
                if (structList != null && structList.size() > 0) {
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<组织标识></b>组织标识已存在");
                }
                int idNum = 0;
                for (int k = 0; k < idList.size(); k++) {
                    if (idList.get(k).equals(map.get("structId").toString())) {
                        idNum = idNum + 1;
                    }
                }
                if (idNum > 1) {
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<组织标识></b>组织标识重复");
                }
                if (!StringUtil.isEmpty(map.get("parentId"))) {
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("structId", map.get("parentId").toString());
                    List<Map<String, Object>> structList0 = priviStructCustomMapper.selPath(map1);
                    boolean parentFlag = false;
                    for (int k = 0; k < idList.size(); k++) {
                        if (idList.get(k).equals(map.get("parentId").toString())) {
                            parentFlag = true;
                            break;
                        }
                    }
                    if ((structList0 == null || structList0.size() == 0) && !parentFlag) {
                        msgFlag=true;
                        sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<父级标识></b>父级标识不存在");
                    }
                }
                String structType = map.get("structType").toString();
                if (!"1".equals(structType) && !"1.0".equals(structType) && !"2".equals(structType) && !"2.0".equals(structType) && !"3".equals(structType) && !"3.0".equals(structType)) {
                    msgFlag=true;
                    sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<组织类型></b>组织类型填写错误");
                }
                if (!StringUtil.isEmpty(map.get("structAttr"))) {
                    String structAttr = map.get("structAttr").toString();
                    boolean attrFlag = false;
                    for (int k = 0; k < attrList.size(); k++) {
                        if (structAttr.equals(attrList.get(k).get("code").toString())) {
                            attrFlag = true;
                            break;
                        }
                    }
                    if (!attrFlag) {
                        msgFlag=true;
                        sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<组织属性标识></b>组织属性标识填写错误");
                    }
                }
                if (!StringUtil.isEmpty(map.get("corpId"))) {
                    String corpId = map.get("corpId").toString();
                    boolean corpFlag = false;
                    for (int k = 0; k < corpList.size(); k++) {
                        if (corpId.equals(corpList.get(k).get("corpId").toString())) {
                            corpFlag = true;
                            break;
                        }
                    }
                    if (!corpFlag) {
                        msgFlag=true;
                        sbf.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<所属法人标识></b>所属法人标识填写错误");
                    }
                }
                if (msgFlag){
                    msg="<span style='color:red;font-weight:bold;'>======>导入失败</span>(请您根据提示修正数据后再完成导入操作)<span style='color:red;font-weight:bold;'><=====</span> <br/>";
                    msg=msg+stringBuffer.append(sbf.toString());
                    fialFlag=true;
                }else{
                    if(!fialFlag){
                        msg= "**********   <span style='color:green;font-weight:bold;'>导入结果：成功</span>   ********** <br/><br/>字段管理共计导入 <span style='color:blue;font-weight:bold;'>"+ list.size() + "</span> 条数据";
                        addList.add(map);
                    }
                }
                n++;
            }
        }
        if (addList.size() > 0) {
            try{
                List<Map<String, Object>> list = priviStructCustomMapper.getMaxSeriaNo();
                Integer serialNo = 1;
                if (list != null && list.size() > 0) {
                    serialNo = Integer.parseInt(list.get(0).get("serialNo").toString());
                }
                for (int i = 0; i < addList.size(); i++) {
                    serialNo = serialNo + i;
                    addList.get(i).put("serialNo", serialNo);
                    addList.get(i).put("userId", userId);
                    addList.get(i).put("time", date);
                    Map<String, Object> map = addList.get(i);
                    if (StringUtil.isEmpty(map.get("parentId"))) {
                        addList.get(i).put("nodePath", "." + map.get("structId").toString() + ".");
                        addList.get(i).put("levelId", 1);
                    } else {
                        String parentId = map.get("parentId").toString();
                        String nodePath = "." + map.get("structId").toString() + ".";
                        Integer levelId = 1;
                        Map<String, Object> map1 = new HashMap<>();
                        map1 = selNodePath(parentId, addList, nodePath, levelId, map1);
                        if (!StringUtil.isEmpty(map1.get("nodePath"))) {
                            addList.get(i).put("nodePath", map1.get("nodePath").toString());
                        }
                        if (!StringUtil.isEmpty(map1.get("levelId"))) {
                            addList.get(i).put("levelId", Integer.parseInt(map1.get("levelId").toString()));
                        }
                    }
                }
                priviStructCustomMapper.addStructList(addList);
            }catch  (Exception e){
                e.printStackTrace();
                msg="<span style='color:red;font-weight:bold;'>======>导入失败</span><span style='color:red;font-weight:bold;'><=====</span> <br/>(导入异常，请修正数据后重新导入)";
                return msg;
            }
        }
        return msg;
    }

    public Map<String, Object> selNodePath(String parentId, List<Map<String, Object>> addList, String nodePath, Integer levelId, Map<String, Object> map1) {
        boolean flag = false;
        for (int i = 0; i < addList.size(); i++) {
            if (addList.get(i).get("structId").toString().equals(parentId)) {
                flag = true;
                nodePath = "." + addList.get(i).get("structId").toString() + nodePath;
                levelId = levelId + 1;
                map1.put("nodePath", nodePath);
                map1.put("levelId", levelId);
                if (!StringUtil.isEmpty(addList.get(i).get("parentId"))) {
                    map1 = selNodePath(addList.get(i).get("parentId").toString(), addList, nodePath, levelId, map1);
                }
                break;
            }
        }
        if (!flag) {
            Map<String, Object> map2 = new HashMap<>();
            map2.put("structId", parentId);
            List<Map<String, Object>> mapList = priviStructCustomMapper.selPath(map2);
            if (mapList != null && mapList.size() > 0) {
                nodePath = "." + parentId + nodePath;
                levelId = levelId + 1;
                map1.put("nodePath", nodePath);
                map1.put("levelId", levelId);
                if (!StringUtil.isEmpty(mapList.get(0).get("parentId"))) {
                    map1 = selNodePath(mapList.get(0).get("parentId").toString(), addList, nodePath, levelId, map1);
                }
            }
        }
        return map1;
    }
}
